using System;
using System.Collections.Generic;
using System.ComponentModel;

using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodePlex.SpaceBlock;
using CodePlex.Resourceful;
using CodePlex.Resourceful.Amazon.S3;
using System.Xml;

namespace CodePlex.SpaceBlock.UI.Controls.Explore
{
    public partial class TransferMetadataForm : CodePlex.SpaceBlock.UI.Controls.BaseForm
    {

        private NameValuePairs _systemMetadata;
        private NameValuePairs _userMetadata;


        public TransferMetadataForm()
        {
            InitializeComponent();


            this.Text = Properties.Messages.TransferMetadata_Title;




            DataGridView userGrid = new DataGridView();

            userGrid.AllowUserToAddRows = true;
            userGrid.AllowUserToDeleteRows = true;

            userGrid.AllowUserToResizeRows = false;
            userGrid.AllowUserToResizeColumns = true;

            userGrid.RowHeadersVisible = true;

            userGrid.Columns.Clear();


            DataGridViewTextBoxColumn nameColumn = new DataGridViewTextBoxColumn();
            nameColumn.Name = "Name";
            nameColumn.Width = 250;
            userGrid.Columns.Add(nameColumn);

            DataGridViewTextBoxColumn valueColumn = new DataGridViewTextBoxColumn();
            valueColumn.Name = "Value";
            valueColumn.Width = 250;
            userGrid.Columns.Add(valueColumn);


            valueColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;


            UIUtils.FillWith(_userGridHolder, userGrid);


        }


        public NameValuePairs SystemMetadata
        {
            get { return _systemMetadata; }
        }

        public NameValuePairs UserMetadata
        {
            get { return _userMetadata; }
        }




        private Metadata ToSystemMetadata(NameValuePairs system)
        {
            Metadata rt = new Metadata();

            NameValuePairs httpHeaders = SpaceBlockUtils.HttpHeaderDescriptions();

            string category = "HTTP";
            foreach (string httpHeader in new string[] 
            { 
                // these are explicitly specified in the S3 docs 
                HttpHeader.CacheControl,
                S3Constants.Headers.ContentDisposition,
                HttpHeader.ContentEncoding,
                HttpHeader.Expires,

            })
            {
                string description = httpHeaders.GetIfExists(httpHeader);

                rt.Set(false, category, httpHeader, description, system.GetIfExists(httpHeader));
            }

            return rt;
        }

        public void Initialize(NameValuePairs system, NameValuePairs user)
        {
            system = system ?? new NameValuePairs();
            user = user ?? new NameValuePairs();


            // system metadata

            Metadata systemMetadata = this.ToSystemMetadata(system);

            _system.Initialize(systemMetadata, TransientSettingsSuggestions.Instance);



            // user metadata

            DataGridView userGrid = _userGridHolder.Controls[0] as DataGridView;

            userGrid.Rows.Clear();

            

            foreach (string key in user.Keys)
            {
                userGrid.Rows.Add(key, user[key]);
            }
        }






        private void _okButton_Click(object sender, EventArgs e)
        {

            // set metadata from current ui values

            // system
            _systemMetadata = new NameValuePairs();
            Metadata meta = _system.Metadata;
            foreach (string name in meta.Keys)
            {
                string value = meta[name];
                if (!string.IsNullOrEmpty(value))
                {
                    _systemMetadata[name] = value;
                }
            }



            // user
            _userMetadata = new NameValuePairs();

            DataGridView userGrid = _userGridHolder.Controls[0] as DataGridView;
            foreach (DataGridViewRow row in userGrid.Rows)
            {

                string name = Convert.ToString(row.Cells[0].Value);
                string value = Convert.ToString(row.Cells[1].Value);

                if (!string.IsNullOrEmpty(name))
                {
                    _userMetadata[name] = value;
                }
            }



            TransientSettingsSuggestions.Instance.Save(_system.Metadata);

        }

      


        private class TransientSettingsSuggestions : IMetadataSuggestions
        {


            private static TransientSettingsSuggestions __instance;
            public static TransientSettingsSuggestions Instance
            {
                get
                {
                    if (__instance == null)
                    {
                        __instance = new TransientSettingsSuggestions();
                    }
                    return __instance;
                }
            }


            private readonly Dictionary<string, List<string>> _keysToSuggestions;

            private TransientSettingsSuggestions()
            {
                _keysToSuggestions = new Dictionary<string, List<string>>();
                this.LoadFromSettings();
            }

            public bool SupportsSuggestions(string key)
            {
                return _keysToSuggestions.ContainsKey(key);
            }

            public IEnumerable<string> GetSuggestions(string key)
            {
                if (this.SupportsSuggestions(key))
                {
                    foreach (string suggestion in _keysToSuggestions[key])
                    {
                        yield return suggestion;
                    }
                }
            }



            public void Save(Metadata metadata)
            {
                foreach (string key in metadata.Keys)
                {
                    string value = metadata[key];
                    if (!string.IsNullOrEmpty(value))
                    {
                        //value = value.Trim();
                        if (!_keysToSuggestions.ContainsKey(key))
                        {
                            _keysToSuggestions.Add(key, new List<string>());
                        }
                        if (!_keysToSuggestions[key].Contains(value))
                        {
                            _keysToSuggestions[key].Add(value);
                            _keysToSuggestions[key].Sort();
                        }
                    }
                }

                this.SaveToSettings();
            }



            private IEnumerable<XmlElement> GetChildElements(XmlElement parent) 
            {
                foreach(XmlNode node in parent.ChildNodes) 
                {
                    if (node is XmlElement)
                    {
                        yield return (XmlElement)node;
                    }
                }
            }

            private void LoadFromSettings()
            {
                _keysToSuggestions.Clear();

                XmlElement settings = TransientSettings.GetSettings("TransferMetadata");


                foreach (XmlElement keyElement in GetChildElements(settings))
                {
                    string key = keyElement.GetAttribute("Key");
                    List<string> values = new List<string>();
                    foreach (XmlElement valueElement in GetChildElements(keyElement))
                    {
                        values.Add(valueElement.GetAttribute("Value"));
                    }
                    _keysToSuggestions.Add(key, values);
                }
            }

            private void SaveToSettings()
            {
                XmlDocument d = new XmlDocument();
                XmlElement settings = d.CreateElement("Settings");

                foreach (KeyValuePair<string, List<string>> kvp in _keysToSuggestions)
                {
                    XmlElement keyElement = d.CreateElement("Key");
                    keyElement.SetAttribute("Key", kvp.Key);

                    foreach (string value in kvp.Value)
                    {
                        XmlElement valueElement = d.CreateElement("Value");
                        valueElement.SetAttribute("Value", value);
                        keyElement.AppendChild(valueElement);
                    }


                    settings.AppendChild(keyElement);
                }

                TransientSettings.SaveSettings("TransferMetadata", settings);

            }



        }




    }
}

